package com.feng.fengDUtil;

import com.feng.fengDUtil.dao.SqlExecutor;
import com.feng.fengDUtil.dao.pojo.InsertTypeEnum;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import javax.sql.DataSource;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public abstract class BaseDao extends MySqlUtil {

  private FengD fengD;

  public void setFengD(FengD fengD) {
    this.fengD = fengD;
  }

  public abstract void init(DataSource dataSource);

  /*   public void beginTranSaction(){
        fengD.connectionManager.beginTranSaction();
    }
    public void commitAndCloseConnection(){
        fengD.connectionManager.commitAndCloseConnection();
    }
    public void closeConnectionByException(boolean hasException){
        fengD.connectionManager.closeConnectionByException(true);
    }
    public void rollbackAndCloseConnection(){
        fengD.connectionManager.rollbackAndCloseConnection();
    }*/

  /**
   * 给分页 page的每条记录添加list. 仅限于 page 中 记录 主键为 id,且为长整型.
   */
  public void setSubListForPage(List<Map> list, Class foreignClass, String foreignName,
      String foreignKey) {
    List<Object> foreignKeyList = new ArrayList<>();
    for (Map rec : list) {
      if (rec.get(foreignKey) != null) {
        foreignKeyList.add(rec.get(foreignKey));
      }
    }
    if (foreignKeyList.size() == 0) {
      return;
    }
    List subList = selectByIds(foreignClass, foreignKeyList);
    for (Map rec : list) {
      for (Object sub : subList) {
        if (rec.get(foreignKey).equals(Reflections.invokeGetter(sub, "id"))) {
          rec.put(foreignName, sub);
        }
      }
    }
  }

  public SqlExecutor sql(String sql) {
    return fengD.sql(sql);
  }

  public Page findPageList(String sql, Page page, Object... params) {
    return findPageList(Map.class, sql, page, params);
  }

  public Page findPageList(Class clazz, String sql, Page page, Object... params) {
    return fengD.findPageList(clazz, sql, page, params);
  }

  public <T> T selectById(Class<T> beanClass, Object id) {
    return fengD.selectById(beanClass, id);
  }

  public <T> List<T> selectByIds(Class<T> beanClass, List ids) {
    return fengD.selectByIds(beanClass, ids);
  }

  public <T> List<T> selectAll(Class<T> beanClass) {
    return fengD.selectAll(beanClass);
  }

  public List<Map> selectAll(String tableName) {
    return fengD.selectAll(tableName);
  }

  public <T> T selectByPk(Class<T> beanClass, Object[] pks) {
    return fengD.selectByPk(beanClass, pks);
  }

  public int insert(Object bean) {
    return fengD.insert(bean, InsertTypeEnum.insert);
  }

  public int insertWithoutNull(Object bean) {
    return fengD.insertWithoutNull(bean, InsertTypeEnum.insert);
  }

  public int insert(Object bean, InsertTypeEnum insertType) {
    return fengD.insert(bean, insertType);
  }

  public int insertWithoutNull(Object bean, InsertTypeEnum insertType) {
    return fengD.insertWithoutNull(bean, insertType);
  }


  public int update(Object bean) {
    return fengD.update(bean);
  }

  public int updateWithoutNull(Object bean) {
    return fengD.updateWithoutNull(bean);
  }

  public int deleteById(Class tableClass, Object id) {
    return fengD.deleteById(tableClass, id);
  }

  public int[] deleteByIds(Class tableClass, String ids, String separator) {
    return fengD.deleteByIds(tableClass, ids, separator);
  }

  public int[] deleteByIds(Class tableClass, String ids) {
    return deleteByIds(tableClass, ids, ",");
  }

  public int deleteByPk(Class tableClass, Object[] pks) {
    return fengD.deleteByPk(tableClass, pks);
  }

  public int delete(Object bean) {
    return fengD.delete(bean);
  }

  public int deleteByWhere(Class tableClass, String whereSql, Object[] params) {
    return fengD.deleteByWhere(tableClass, whereSql, params);
  }

  public int[] batch(String sql, Object[][] params) {
    return fengD.batch(sql, params);
  }

  public int[] batch(String sql, Object[] params) {
    return fengD.batch(sql, params);
  }

  public int[] batch(String sql, List<Object[]> params) {
    return fengD.batch(sql, params);
  }

  public Object startTranSaction(Callable callable) {
    return fengD.startTranSaction(callable);
  }

  public void saveOrUpdate(Object bean) {
    fengD.saveOrUpdate(bean);
  }

  public void saveOrUpdateAll(List beans) {
    fengD.saveOrUpdateAll(beans);
  }

  public boolean isUnique(Class clazz, String fieldName, String fieldVal, Object id) {
    return fengD.isUnique(clazz, fieldName, fieldVal, id);
  }

  public void insertBatch(List beans) {
    fengD.insertBatch(beans, InsertTypeEnum.insert);
  }

  public void insertBatch(List beans, InsertTypeEnum insertType) {
    fengD.insertBatch(beans, insertType);
  }
}
